import React, { useCallback, useState } from 'react'

let Child = (props)=>{
  console.log('Child 被执行了');
  return (<div>
    Child --- {props.name}

    <button onClick={()=>{
      // 3. 在子组件中触发修改
      props.changeName('李四')
    }}>点击修改名称</button>
  </div>)
}

Child = React.memo(Child)

const App = () => {

    const [count,setCount] = useState(100)
    const [name,setName] = useState('张三')

    // 1. 父组件先定义修改的函数
    let changeName = (val)=>{
      setName(val)
    }

    /*
      useCallback 可以接受两个参数，会有一个返回值
      参数一：是一个函数，就是我们需要缓存的函数
      参数二：是一个依赖项，只有依赖项被改变之后，才会重新执行前面的函数

      useCallback 将使用的函数包裹起来，可以将这些函数进行缓存
    */ 
    changeName = useCallback(changeName, [])

    return (
      <div >

        <h1>{count}</h1>
        <button onClick={()=>{
          setCount(count + 1)
        }}> 点击加 1 </button>
        <hr />

        {/* 2. 将修改函数传递给子组件 */}
        <Child name={name} changeName={changeName} />
      </div>
  )
}
/*
  父组件给子组件传递一个 name 属性
  此时父组件修改 count 不会影响到子组件重新渲染

  在给子组件传递一个修改函数 changeName 
  此时父组件修改 count 会导致子组件重新渲染

  原因：
    因为 changeName 是父组件的一个函数，当 count 值发生改变的时候，会导致父组件重新渲染
    父组件一旦重新渲染就会导致重新创建一个 changeName 函数，changeName又被传递给 Child
    组件中了，所以当父组件发生变化的时候又会导致 Child 组件被重新渲染

* */ 

export default App